package com.sinocst.sap3;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
 * @Project: JavaWebSAPAPI
 * @Author: zhang10092009@hotmail.com
 * @Date: 2018/2/26  14:15
 * @Description:
 */
public class WebiReportFor40Sample {
    /**
     * CMS System
     */
    private static final String CMS_LOG_HOST = "10.173.1.153:6405";
    private String unxName = "eFashion_IQ_Auto.unx";
    private String folderID = "5652";
    private String dataSourceID;
    /**
     * User name used to log in to the CMS
     */
    private static final String CMS_LOG_USER = "Administrator";
    /**
     * User password
     */
    private static final String CMS_LOG_PASS = "SAPoem123";
    /**
     * Authentication mode used to log in to the CMS. Here: Enterprise
     */
    private static final String CMS_AUTH_MODE = "secEnterprise";
    private static final String WEBI_URL = "/biprws/raylight/v1";
    private static final String SL_URL = "/biprws/raylight/v1";
    private String logonToken;
    private boolean isLogon = false;
    private String fileName = "eFashioin_IQ_Auto";
    private String documentID;
    private String reportID = "1";
    private String dataProviderID;

    public static void main(String[] args) throws JSONException, ParseException, IOException {
        WebiReportFor40Sample webiRep = new WebiReportFor40Sample();
        JSONObject json = null;
        String resultStr = null;
        webiRep.getLogonToken();
        json = webiRep.createDoc();
        json = webiRep.addDataProviderInReport();
        json = webiRep.refreshDocument();
        json = webiRep.updateStructureInReport();
        json = webiRep.refreshDocumentWithData();
        json = webiRep.updateDocumentProps();
        webiRep.saveDocument();
        System.out.println(resultStr);
        if (json != null) {
            System.out.println(json.toString());
        }
    }

    public JSONObject createDoc() throws IOException, ParseException, JSONException {
        String body = "<document>"
                + "<name>" + this.fileName + "</name>"
                + "<folderId>" + this.folderID + "</folderId>"
                + "<refreshOnOpen>true</refreshOnOpen>"
                + "</document>";
        JSONObject json = postContentJson("http://" + CMS_LOG_HOST + WEBI_URL + "/documents", body);
        this.documentID = json.getJSONObject("success").getString("id");
        return json;
    }

    public JSONObject saveDocument() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/" + this.documentID;
        String body = "<document>" + "</document>";
        // System.out.println(urlStr);
        // JSONObject json = postContentJson(urlStr, body);
        JSONObject json = this.putXmlContentJson(urlStr, body);
        return json;
    }

    public JSONObject updateDocumentProps() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/" + this.documentID + "/properties";
        String body = "<properties>"
                + " <property key=\"refreshonopen\">true</property>"
                + "</properties>";
        // System.out.println(urlStr);
        // JSONObject json = postContentJson(urlStr, body);
        JSONObject json = this.putXmlContentJson(urlStr, body);
        return json;
    }

    public JSONObject addDataProviderInReport() throws IOException, ParseException, JSONException {
        this.dataSourceID = this.getUniverseID(unxName);
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/" + this.documentID + "/dataproviders";
        String body = "<dataprovider>"
                + "<name>Query 1</name>"
                + "<dataSourceId>" + this.dataSourceID + "</dataSourceId>"
                + "</dataprovider>";
        JSONObject json = postContentJson(urlStr, body);
        this.dataProviderID = json.getJSONObject("success").getString("id");
        json = addQueryInDataProvider();
        return json;
    }

    public JSONObject updateStructureInReport() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/" + this.documentID + "/reports/" + this.reportID + "/specification";
        // int i = 0;
        String body = "<REPORT rId=\"1\" name=\"Report 1\">"
                + " <PAGEDEF>"
                    + " <MARGIN bottom=\"2835\" top=\"2835\" left=\"2835\" right=\"2835\" />"
                    + " <RECORDS horizontal=\"20\" vertical=\"100\" />"
                + " </PAGEDEF>"
                + " <PAGE_HEADER bId=\"1\" />"
                + " <PAGE_BODY bId=\"2\">"
                + " <CELL bId=\"4\" x=\"7416\" y=\"432\" width=\"15048\" height=\"1548\">"
                    + " <STYLE>"
                        + " <BORDER side=\"bottom\" width=\"0\" style=\"none\" />"
                        + " <FONT size=\"16\" bold=\"no\" underline=\"yes\" />"
                    + " </STYLE>"
                    + " <CONTENT>=ReportName()</CONTENT>"
                + " </CELL>"
                + " <VTABLE bId=\"11\" name=\"Block 1\" x=\"450\" y=\"900\"" + " verticalAttachTo=\"4\" verticalAttachType=\"bottom\">"
                + " <AXIS>"
                    + " <EXPRS>"
                    + " <AXIS_EXPR>=[YR]</AXIS_EXPR>"
    //                + " <AXIS_EXPR>=[QUANTITY SOLD]</AXIS_EXPR>"
                    + " </EXPRS>"
                    + " <HIDE />"
                    + " <ALTCOLOR frequency=\"2\" />"
                + " </AXIS>"
                + " <DATA />"
                + " <COL width=\"0\" />"
                + " <COL width=\"0\" />"
                + " <ROWGROUP type=\"header\">"
                    + " <TR height=\"0\">"
                        + " <TDCELL bId=\"8\">" + " <CONTENT>=NameOf([YR])</CONTENT>" + " </TDCELL>"
                        + " <TDCELL bId=\"9\">" + " <CONTENT>=NameOf([QUANTITY SOLD])</CONTENT>" + " </TDCELL>" + " "
                    + " </TR>"
                + " </ROWGROUP>"
                + " <ROWGROUP type=\"body\">"
                + " <TR height=\"0\">"
                    + " <TDCELL bId=\"5\">" + " <CONTENT>=[YR]</CONTENT>" + " </TDCELL>"
                    + " <TDCELL bId=\"6\">" + " <CONTENT>=[QUANTITY SOLD]</CONTENT>" + " </TDCELL>"
                + " </TR>"
                + " </ROWGROUP>"
                + " </VTABLE>"
                + " </PAGE_BODY>"
                + " <PAGE_FOOTER bId=\"3\" />"
                + " </REPORT> ";
        JSONObject json = this.putTextContentJson(urlStr, body);
        // this.dataProviderID = json.getJSONObject("success").getString("id");
        // json = this.saveDocument();
         return json;
    }
    public JSONObject addQueryInDataProvider() throws IOException,    ParseException, JSONException {
            String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/"
                    + this.documentID + "/dataproviders/" + this.dataProviderID + "/specification";
    //         int i = 0;
             String body = "<queryspec:QuerySpec xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
                 + " xmlns:queryspec=\"http://com.sap.sl.queryspec\" dataProviderId=\"" + this.dataProviderID + "\" version=\"17\" >"
                     + " <queryParameters>"
                         + " <duplicatedRowsProperty activated=\"true\" value=\"true\"/>"
                         + " <maxRetrievalTimeInSecondsProperty value=\"300\"/>"
                         + " <maxRowsRetrievedProperty value=\"90000\"/>"
                         + " <removeEmptyRowsProperty activated=\"true\" value=\"true\"/>"
                         + " <allowOtherUserToEditQueryProperty activated=\"true\" value=\"true\"/>"
                         + " <resetContextOnRefreshProperty activated=\"true\" value=\"true\"/>"
                         + " <stripQueryProperty/>"
                     + " </queryParameters>"
                     + " <queriesTree xsi:type=\"queryspec:QueryDataNode\">"
        //                 + " <children xsi:type=\"queryspec:QueryDataNode\">"
                         + " <bOQuery name=\"Query\" " + "identifier=\"_" + this.documentID + "_" + this.dataProviderID + "_" + "query\"" + ">"
                             + " <resultObjects " + "identifier=\"" + this.getDimensionID(this.dataSourceID, "YR") + "\" " + "name=\"YR\"/>"
                             + " <resultObjects " + "identifier=\"" + this.getDimensionID(this.dataSourceID, "QUANTITY SOLD") + "\" " + "name=\"QUANTITY SOLD\"/>"
                             + " <conditionPart/>"
                         + " </bOQuery>"
                     + " </queriesTree>"
                 + " </queryspec:QuerySpec>";
             JSONObject json = putTextContentJson(urlStr, body);
             return json;
    }
    public JSONObject refreshDocument() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/"
        // + this.documentID + "/parameters?refresh=true";
             + this.documentID + "/parameters";
        // JSONObject json = this.putXmlContentJson(urlStr, "");
           JSONObject json = this.getContentJson(urlStr);
           return json;
    }
    public JSONObject refreshDocumentWithData() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/" + this.documentID + "/parameters";
        JSONObject json = this.putXmlContentJson(urlStr, "");
        return json;
    }
    public String getLogonToken() throws ParseException, IOException, JSONException {
        String body = "<attrs xmlns=\"http://www.sap.com/rws/bip\">" + "<attr name=\"userName\" type=\"string\">"
                + CMS_LOG_USER + "</attr>"
                + "<attr name=\"password\" type=\"string\">" + CMS_LOG_PASS + "</attr>"
                + "<attr name=\"auth\" type=\"string\" possibilities=\"secEnterprise,secLDAP,secWinAD\">"
                + CMS_AUTH_MODE + "</attr>" + "</attrs>";
                JSONObject json = postContentJson("http://" + CMS_LOG_HOST + "/biprws/logon/long/", body);
                logonToken = (String) json.get("logonToken");
                isLogon = true;
                return logonToken;
    }
    private JSONObject getContentJson(String urlStr) throws IOException, JSONException {
        System.out.println(urlStr);
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        if (this.isLogon) {
            conn.setRequestProperty("X-SAP-LogonToken", "\"" + logonToken + "\"");
        }
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Content-Type", "application/xml; charset=utf-8");
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.connect();
        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
        String jsontxt = br.readLine();
        br.close();
        JSONObject json = new JSONObject(jsontxt);
        conn.disconnect();
        return json;
    }
    private String getUniverseID(String universeName) throws IOException,    JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + SL_URL + "/universes";
        JSONObject json = this.getContentJson(urlStr);
        JSONArray universeArray = json.getJSONObject("universes").getJSONArray(     "universe");
        for (int i = 0; i < universeArray.length(); i++) {
            if (universeName.equals(universeArray.getJSONObject(i).getString("name"))) {
                return universeArray.getJSONObject(i).getString("id");
            }
        }
        return null;
    }
    private String getContentStr(String urlStr, String acceptType)throws IOException, JSONException {
        return getAndDeleteContentStr(urlStr, acceptType, "GET");
    }
    private String getAndDeleteContentStr(String urlStr, String acceptType, String method) throws IOException, JSONException { System.out.println(urlStr);
    URL url = new URL(urlStr);   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod(method);
    if (this.isLogon) {
        conn.setRequestProperty("X-SAP-LogonToken", "\"" + logonToken      + "\"");
    }   conn.setRequestProperty("Accept", acceptType);
    conn.setRequestProperty("Content-Type",     "application/xml; charset=utf-8");
    conn.setDoOutput(true);   conn.setDoInput(true);   conn.connect();
    if (conn.getResponseCode() != 200) {
        throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
    }
    byte[] buffer = new byte[1024];
    String sFinal = "";
    int bytesRead = 0;
    BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
    while ((bytesRead = bis.read(buffer)) != -1) {
        sFinal = sFinal + new String(buffer, 0, bytesRead);
    }
    bis.close();
    conn.disconnect();
    return sFinal;
    }
    private JSONObject postContentJson(String urlStr, String body)    throws IOException, JSONException {
        return postAndPutContentJson(urlStr, body, "POST",     "application/xml; charset=utf-8");
    }
    private JSONObject putTextContentJson(String urlStr, String body)    throws IOException, JSONException {
        return postAndPutContentJson(urlStr, body, "PUT",     "text/xml; charset=utf-8");
    }
    private JSONObject putXmlContentJson(String urlStr, String body)    throws IOException, JSONException {
        return postAndPutContentJson(urlStr, body, "PUT",     "application/xml; charset=utf-8");
    }
    private String getDimensionID(String dataSourceID, String dimensionName) throws IOException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + SL_URL + "/universes/" + this.dataSourceID;
        JSONObject json = this.getContentJson(urlStr);
        JSONArray folderArray = json.getJSONObject("universe").getJSONObject("outline").getJSONArray("folder");
        for (int i = 0; i < folderArray.length(); i++) {
            JSONArray itemArray = folderArray.getJSONObject(i).getJSONArray("item");
            for (int j = 0; j < itemArray.length(); j++) {
                if (dimensionName.equals(itemArray.getJSONObject(j).getString("name"))) {
                    return itemArray.getJSONObject(j).getString("id");
                }
            }
        }
        return null;
    }
    private JSONObject postAndPutContentJson(String urlStr, String body, String method, String contentType) throws IOException, JSONException {
        System.out.println(urlStr);
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        if (this.isLogon) {
            conn.setRequestProperty("X-SAP-LogonToken", "\"" + logonToken + "\"");
        }
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Content-Type", contentType);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        int len = body.length();
        conn.setRequestProperty("Content-Length", Integer.toString(len));
        conn.connect();
        OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
        out.write(body, 0, len);
        out.flush();
        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
        String jsontxt = br.readLine();
        br.close();
        conn.disconnect();
        JSONObject json = new JSONObject(jsontxt);
        return json;
    }
}
